package com.atguigu.tingshu.album.service.impl;

import java.math.BigDecimal;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.order.TrackPayVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

    @Autowired
    private TrackInfoMapper trackInfoMapper;
    @Autowired
    private VodUploadClient client;
    @Autowired
    private VodConstantProperties vodConstantProperties;

    @Autowired
    private TrackStatMapper trackStatMapper;

    @Autowired
    private AlbumStatMapper albumStatMapper;
    @Autowired
    private VodService vodService;
    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Override
    public UploadTrackVo trackInfoService(MultipartFile file) {

        //把上传的文件数据存储到本地磁盘上 形成临时数据 返回临时文件的路径 删除临时文件
        String uploadTempPath = UploadFileUtil.uploadTempPath(vodConstantProperties.getTempPath(), file);
        //创建请求对象 封装请求参数
        VodUploadRequest request = new VodUploadRequest();
        request.setMediaFilePath(uploadTempPath);
        request.setProcedure(vodConstantProperties.getProcedure());

        //发送文件上传的请求
        VodUploadResponse response = null;

        try {
            response = client.upload(vodConstantProperties.getRegion(), request);
            //获取请求返回的数据
            String fileId = response.getFileId();
            String mediaUrl = response.getMediaUrl();
            //构建响应结果数据
            UploadTrackVo uploadTrackVo = new UploadTrackVo();
            uploadTrackVo.setMediaFileId(fileId);
            uploadTrackVo.setMediaUrl(mediaUrl);
            return uploadTrackVo;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            new File(uploadTempPath).delete();
        }
    }

    @Transactional
    @Override
    public void saveTrackInfo(TrackInfoVo trackInfoVo) {
        Long userId = AuthContextHolder.getUserId();
        //保存声音的基本数据
        TrackInfo trackInfo = new TrackInfo();
        BeanUtils.copyProperties(trackInfoVo, trackInfo);
        trackInfo.setUserId(userId);
        trackInfo.setSource(SystemConstant.TRACK_SOURCE_UPLOAD);
        trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
        //查询当前专辑下的最大声音值数据
        LambdaQueryWrapper<TrackInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TrackInfo::getAlbumId, trackInfo.getAlbumId());
        queryWrapper.orderByDesc(TrackInfo::getOrderNum);
        queryWrapper.last("limit 1");
        TrackInfo dbTrackInfo = trackInfoMapper.selectOne(queryWrapper);
        if (dbTrackInfo != null) {
            trackInfo.setOrderNum(dbTrackInfo.getOrderNum() + 1);
        } else {
            trackInfo.setOrderNum(1);
        }
        //请求云点播接口获取相关数据
        TrackMediaInfoVo trackMediaInfo = vodService.getTrackMediaInfo(trackInfoVo.getMediaFileId());
        trackInfo.setMediaDuration(new BigDecimal(trackMediaInfo.getDuration()));
        trackInfo.setMediaUrl(trackMediaInfo.getMediaUrl());
        trackInfo.setMediaSize(trackMediaInfo.getSize());
        trackInfo.setMediaType(trackMediaInfo.getType());
        trackInfoMapper.insert(trackInfo);

        //初始化声音的统计数据
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COLLECT);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PRAISE);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COMMENT);

        //更改album_info表中声音统计值字段值+1
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());
        Integer includeTrackCount = albumInfo.getIncludeTrackCount();
        albumInfo.setIncludeTrackCount(includeTrackCount + 1);
        albumInfoMapper.updateById(albumInfo);
    }

    @Override
    public IPage<TrackListVo> findUserTrackPage(Integer pageNum, Integer pageSize, TrackInfoQuery trackInfoQuery) {
        //获取用户id
        Long userId = AuthContextHolder.getUserId();
        trackInfoQuery.setUserId(userId);
        IPage<TrackListVo> page = new Page<>(pageNum, pageSize);
        trackInfoMapper.findUserTrackPage(page, trackInfoQuery);
        return page;
    }

    @Override
    public void updateTrackInfo(Long trackId, TrackInfoVo trackInfoVo) {
        //根据声音的id查询声音数据
        TrackInfo dbTrackInfo = trackInfoMapper.selectById(trackId);
        String mediaFileId = trackInfoVo.getMediaFileId();
        String dbMediaFileId = dbTrackInfo.getMediaFileId();
        BeanUtils.copyProperties(trackInfoVo, dbTrackInfo);
        if (!mediaFileId.equals(dbMediaFileId)) {
            TrackMediaInfoVo trackMediaInfo = vodService.getTrackMediaInfo(mediaFileId);
            dbTrackInfo.setMediaDuration(new BigDecimal(trackMediaInfo.getDuration()));
            dbTrackInfo.setMediaUrl(trackMediaInfo.getMediaUrl());
            dbTrackInfo.setMediaSize(trackMediaInfo.getSize());
            dbTrackInfo.setMediaType(trackMediaInfo.getType());

            vodService.deleteMediaFile(dbMediaFileId);

        }
        trackInfoMapper.updateById(dbTrackInfo);

    }

    @Override
    public void removeTrackInfo(Long trackId) {
        //根据声音id查询声音数据
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        //删除声音基本属性
        trackInfoMapper.deleteById(trackId);
        //删除声音统计信息
        trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId, trackId));
        //修改album_info表中的字段
        Long albumId = trackInfo.getAlbumId();
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() - 1);
        albumInfoMapper.updateById(albumInfo);
        //删除云点播文件
        vodService.deleteMediaFile(trackInfo.getMediaFileId());
    }

    @Override
    public IPage<AlbumTrackListVo> findAlbumTrackPage(Long albumId, Integer pageNum, Integer pageSize) {
        //查询专辑数据
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        //根据用户id查询用户信息
        UserInfo userInfo = userInfoFeignClient.getUserInfoById(albumInfo.getUserId()).getData();
        Integer isVip = userInfo.getIsVip();

        //创建一个page对象
        IPage<AlbumTrackListVo> page = new Page<>(pageNum, pageSize);
        //调用mapper方法查询数据
        trackInfoMapper.AlbumTrackListVo(page, albumId);
        //获取当前页的数据
        List<AlbumTrackListVo> albumTrackListVoList = page.getRecords();
        //构建声音付费字段的值
        Long userId = AuthContextHolder.getUserId();
        //获取专辑的付费类型
        String payType = albumInfo.getPayType();
        Integer tracksForFree = albumInfo.getTracksForFree(); //获取免费试听的集数
        if (userId == null) {
            //判断专辑的付费类型
            //不是免费专辑
            if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(payType)) {
                albumTrackListVoList.stream().filter(track -> track.getOrderNum() > tracksForFree)
                        .forEach(track -> track.setIsShowPaidMark(true));//更改不是试听集数的付费标识
            }
        } else {
            //判断专辑的付费类型
            if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType)) {
                if (isVip.equals(1)) {
                    long vipExpireTime = userInfo.getVipExpireTime().getTime();
                    long timeMillis = System.currentTimeMillis();
                    //vip已经过期
                    if (timeMillis > vipExpireTime) {
                        albumTrackListVoList.stream().filter(track -> track.getOrderNum() > tracksForFree)
                                .forEach(track -> track.setIsShowPaidMark(true));//更改不是试听集数的付费标识
                    }
                } else {
                    albumTrackListVoList.stream().filter(track -> track.getOrderNum() > tracksForFree)
                            .forEach(track -> track.setIsShowPaidMark(true));//更改不是试听集数的付费标识
                }
            } else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(payType)) { //当前专辑是付费的
                //获取非试听声音的id
                List<Long> collect = albumTrackListVoList.stream()
                        .filter(track -> track.getOrderNum() > tracksForFree)
                        .map(AlbumTrackListVo::getTrackId)
                        .collect(Collectors.toList());

                //调用user微服务查询用户是否购买过声音 需要传递两个参数 专辑的id和声音id的集合
                Map<Long, Long> result = userInfoFeignClient.userIsPaidTrack(albumId, collect).getData();
                albumTrackListVoList.stream().filter(track -> track.getOrderNum() > tracksForFree).forEach(track -> {
                    Long trackId = track.getTrackId();
                    Long isPaid = result.get(trackId);
                    Boolean isShowPaidMark = isPaid.intValue() == 1 ? false : true;
                    track.setIsShowPaidMark(isShowPaidMark);
                });
            }
        }
        return page;
    }

    @Override
    public void updateTrackStat(TrackStatMqVo trackStatMqVo) {
        //获取trackStatMqVo中的统计类型
        String statType = trackStatMqVo.getStatType();
        if (SystemConstant.TRACK_STAT_PLAY.equals(statType)) {
            //更新声音的播放量
            TrackStat trackStat = trackStatMapper.selectOne(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId, trackStatMqVo.getTrackId())
                    .eq(TrackStat::getStatType, SystemConstant.TRACK_STAT_PLAY));
            trackStat.setStatNum(trackStat.getStatNum() + trackStatMqVo.getCount());
            trackStatMapper.updateById(trackStat);
            //更新专辑的播放量
            AlbumStat albumStat = albumStatMapper.selectOne(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, trackStatMqVo.getAlbumId())
                    .eq(AlbumStat::getStatType, SystemConstant.ALBUM_STAT_PLAY));
            albumStat.setStatNum(albumStat.getStatNum() + trackStatMqVo.getCount());
            albumStatMapper.updateById(albumStat);
        }

    }

    @Override
    public TrackStatVo getTrackStatVoByTrackId(Long trackId) {
        return trackStatMapper.getTrackStatVoByTrackId(trackId);
    }

    @Override
    public List<TrackPayVo> findUserTrackPaidList(Long trackId) {
        //根据用户所点击的声音id查询声音信息
        //1.1  先根据trackId查询声音信息
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);

        //根据专辑id查询专辑信息
        Long albumId = trackInfo.getAlbumId();
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);

        //1.2 根据声音信息中的专辑id和声音的ordernum进行条件查询
        List<TrackInfo> trackInfos = trackInfoMapper.selectList(new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, trackInfo.getAlbumId())
                .gt(TrackInfo::getOrderNum, trackInfo.getOrderNum()));

        //查询用户购买过的声音集合
        List<Long> trackIds = userInfoFeignClient.findUserTrackPaidList(trackInfo.getAlbumId()).getData();

        //创建List集合 存储用户构建声音分集列表声音的id
        List<Long> trackIdNoReaptList = new ArrayList<>();
        if (CollectionUtils.isEmpty(trackIds)) {
            trackIdNoReaptList = trackInfos.stream().map(track -> track.getId()).collect(Collectors.toList());
        } else { //存在购买的声音id 从trackInfos排除购买过的声音id 得到没有购买的声音id集合
            trackIdNoReaptList = trackInfos.stream().map(track -> track.getId()).filter(streamTrackId -> !trackIds.contains(trackId)).collect(Collectors.toList());
        }
        //创建一个List,存储构建声音分集列表数据
        List<TrackPayVo> trackPayVoList = new ArrayList<>();

        TrackPayVo trackPayVo = new TrackPayVo();
        trackPayVo.setName("本集");
        trackPayVo.setPrice(albumInfo.getPrice());
        trackPayVo.setTrackCount(0);
        trackPayVoList.add(trackPayVo);

        int size = trackIdNoReaptList.size();
        if(size >0 && size <= 10){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(size)));
            trackVo.setName("后" + size + "集");
            trackVo.setTrackCount(size);
            trackPayVoList.add(trackVo);
        }
        if(size > 10){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(10)));
            trackVo.setName("后10集");
            trackVo.setTrackCount(10);
            trackPayVoList.add(trackVo);
        }
        if(size > 10 && size <= 20){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(size)));
            trackVo.setName("后" + size + "集");
            trackVo.setTrackCount(size);
            trackPayVoList.add(trackVo);
        }
        if(size > 20){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(20)));
            trackVo.setName("后20集");
            trackVo.setTrackCount(20);
            trackPayVoList.add(trackVo);
        }
        if(size > 20 && size <= 30){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(size)));
            trackVo.setName("后" + size + "集");
            trackVo.setTrackCount(size);
            trackPayVoList.add(trackVo);
        }
        if(size > 30){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(30)));
            trackVo.setName("后30集");
            trackVo.setTrackCount(30);
            trackPayVoList.add(trackVo);
        }
        if(size > 30 && size <= 40){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(size)));
            trackVo.setName("后" + size + "集");
            trackVo.setTrackCount(size);
            trackPayVoList.add(trackVo);
        }
        if(size > 40){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(40)));
            trackVo.setName("后40集");
            trackVo.setTrackCount(40);
            trackPayVoList.add(trackVo);
        }
        if(size > 40 && size <= 50){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(size)));
            trackVo.setName("后" + size + "集");
            trackVo.setTrackCount(size);
            trackPayVoList.add(trackVo);
        }
        if(size > 50){
            TrackPayVo trackVo = new TrackPayVo() ;
            trackVo.setPrice(albumInfo.getPrice().multiply(new BigDecimal(50)));
            trackVo.setName("后50集");
            trackVo.setTrackCount(50);
            trackPayVoList.add(trackVo);
        }

        return trackPayVoList;
    }

    @Override
    public List<TrackInfo> findPaidTrackInfoList(Long trackId, Integer trackCount) {
        //创建一个list集合存储声音数据
        List<TrackInfo> trackInfoList = new ArrayList<>();

        // 根据声音Id 获取到声音对象
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        // 获取已支付的声音id列表
        List<Long> longs = userInfoFeignClient.findUserTrackPaidList(trackInfo.getAlbumId()).getData();
        //判断trackCount是否大于0,如果大于0返回的list集合中包含多个声音数据
        if(trackCount > 0){
            LambdaQueryWrapper<TrackInfo> queryWrapper = new LambdaQueryWrapper<TrackInfo>();
            queryWrapper.eq(TrackInfo::getAlbumId, trackInfo.getAlbumId());
            queryWrapper.gt(TrackInfo::getOrderNum, trackInfo.getOrderNum());
            if(!CollectionUtils.isEmpty(longs)){
                queryWrapper.notIn(TrackInfo::getId, longs);
            }
            queryWrapper.orderByAsc(TrackInfo::getOrderNum);
            queryWrapper.last("limit" + trackCount);
            trackInfoList = trackInfoMapper.selectList(queryWrapper);
        }else{
            trackInfoList.add(trackInfo);
        }
        return trackInfoList;
    }


    public void saveTrackStat(Long trackId, String statType) {
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackId);
        trackStat.setStatType(statType);
        trackStat.setStatNum(0);
        trackStatMapper.insert(trackStat);
    }


}
